
import java.io.IOException;
import java.util.Random;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.TiledLayer;

/**
 * 
 * @author hanying zheng
 *
 */
public class MainScreenLv2 extends GameCanvas implements Runnable, CommandListener {

	private Thread thread;
	
	private MobilePong parent = null;
	
	private Image backgroundImg;
	
	private TiledLayer background;
	
	private LayerManager layerManager;
	
	private final static Random random = new Random();

	private final int height;
	
	private final int width;
	
	private int paddle_dx = 0;

	private int ball_dx = 0;
	
	private int ball_dy = 0;
	
	private int bg_y = 0;
	
	private int bg_y0 = 0;
	
	private BrickLv2[] bricks;
	
	private BrickLv2[] wallBricks;	//For FALL_MODE
	
	private BallLv2 ball;
	
	private BrickLv2 paddle;
	
	private BrickLv2 oppPaddle;
	
	private int score = 0;
	
	private int scoreInFallMode = 0;
	
	private int maxScore = 0;
	
	private String scoreStr;
	
	private boolean failed = false;
	
	private boolean win = false;
	
	private int phase;
	
	private static final int P_HIT_BLOCK = 0;
	
	private static final int P_HIT_BLOCK_2 = 1;

	private static final int P_HIT_BLOCK_3 = 2;

	private static final int P_BEFORE_FIGHT = 200;
	
	private static final int P_FIGHT = 201;
	
	private static final int P_FALL_MODE_1 = 300;

	private static final int P_FALL_MODE_2 = 301;
	
	private int numOfBrickPerLine = 0;
	
	private int numOfLine = 0;
	
	private int brickWidth = 0;
	
	private boolean fallModeEnd = false;
	
	private boolean readyForHitMode = false;
	
	private int hidenLineNum = 0;
	
	private MusicPlayerLv2 musicPlayer = null;
	
	/**
	 * background cell
	 */
	int[] cells =
	{ 
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			5, 1, 1, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4,
			2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 2, 4};

	int[] brickTypes = 
		{	1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1
		};

	private int[] brickGrounds = {
			2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
			2, 2, 2, 2, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2,
			2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2,
			2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
			2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2,
			2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
			2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2,
			2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2
	};
	
	
	
	public MainScreenLv2(MobilePong parent) {
		super(false);
		
		this.parent = parent;
		height = getHeight();
		width = getWidth();
		phase = this.P_FALL_MODE_1;
		
		parent.updateIndicator(null, true);
		
		layerManager = new LayerManager();
		
		try {
			layerManager.append(createBackground());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		this.ball = new BallLv2(width / 2, height / 2, -5, -5, width);
		
		this.paddle = new BrickLv2(height - 30, width / 2 - 20, 40, 10, BrickLv2.T_FIXED);
		this.oppPaddle = new BrickLv2(20, width / 2, 40, 10, BrickLv2.T_FIXED);
		
		int brickLen = brickTypes.length;
		this.bricks = new BrickLv2[brickLen];
		int row = 0;
	    int column = 0;
		for (int i = 0; i < brickLen; i++) {
			column = i % 10;
			row = i / 10;
			this.bricks[i] = new BrickLv2(20 + row * 12, 20 + column * 20, 18, 10, brickTypes[i]);
			if (brickTypes[i] == BrickLv2.T_NORMAL) {
				maxScore++;
			}
		}
		
		parent.updateIndicator(null, true);
		
		//ground brick initialization
		int wallBrickLen = brickGrounds.length;
		this.wallBricks = new BrickLv2[wallBrickLen];
	    numOfBrickPerLine = 15;
	    brickWidth = width / numOfBrickPerLine;
	    numOfLine = wallBrickLen / numOfBrickPerLine;
	    int h = height / numOfLine;
		for (int i = 0; i < wallBrickLen; i++) {
			column = i % numOfBrickPerLine;
			row = i / numOfBrickPerLine;
			this.wallBricks[i] = new BrickLv2( row * h, column * brickWidth, brickWidth, 10, brickGrounds[i]);
		}
		//end of ground brick initialization
		
		scoreStr = "score:" + score;
		
		parent.updateIndicator(null, true);
		
		thread = new Thread(this);
		thread.start();
	}
	
	private TiledLayer createBackground() throws IOException {
	    backgroundImg = Image.createImage("/bgLv2.png");				//load the image
	    background = new TiledLayer(50, 200, backgroundImg, 16, 16);	//background
	    int row = 0;
	    int column = 0;
	    for (int i = 0; i < cells.length; i++) { 						//set background with images
			column = i % 15;
			row = i / 15;
			background.setCell(column, row, cells[i]);
	    }

	    int GAME_ORIGIN_X = 0;
	    int GAME_ORIGIN_Y = 0;
	    // set the location of the background
	    background.setPosition(GAME_ORIGIN_X, GAME_ORIGIN_Y);
	    
	    bg_y0 = -(row - 18) * 15;
	    bg_y = bg_y0;
	    
	    return background;
	}

	public void run() {
		if (audio.mode) {
			musicPlayer = new MusicPlayerLv2();
			musicPlayer.setMusicOn(true);
			musicPlayer.startPlay();
		}
		Display.getDisplay(parent).setCurrent(this);
		int uu = 0;
		int score1 = maxScore / 2;
		int score2 = maxScore - 10;
		try {
			while(failed == false && win == false) {
				repaint();
				if (phase == this.P_FALL_MODE_1) {
					generateWallForFallMode();
					ballMoveForFallMode();
					for (int i = this.wallBricks.length - 1; i > -1; i--) {
						this.wallBricks[i].top-=2;
					}
				} else {
					movePaddle();
					ball.move();
					detectCollision();
				}
				
				switch (phase) {
				case P_HIT_BLOCK:
					if (score - this.scoreInFallMode >= score1) {
						phase = this.P_HIT_BLOCK_2;
					}
					break;
				case P_HIT_BLOCK_2:
					for (int i = this.bricks.length - 1; i > -1; i--) {
						this.bricks[i].top+=2;
					}
					if (uu++ > 35) {
						phase = this.P_HIT_BLOCK_3;
					}
					break;
				case P_HIT_BLOCK_3:
					if (score - this.scoreInFallMode >= score2) {
						for (int i = this.bricks.length - 1; i > -1; i--) {
							if (this.bricks[i].type == BrickLv2.T_NORMAL) {
								this.bricks[i].setType(BrickLv2.T_FIXED);
							}
						}
						phase = this.P_FIGHT;
					}
					break;
				case P_FIGHT:
					oppPaddleMove();
					break;
				case P_FALL_MODE_1:
					if (readyForHitMode == true) {
						this.phase = this.P_HIT_BLOCK;
						this.scoreInFallMode = this.score;
					}
				}
				
				Thread.currentThread().sleep(40);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		repaint();
		try {
			Thread.currentThread().sleep(4000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		if (musicPlayer != null) {
			musicPlayer.stopPlay();
		}
		parent.exitLv2();
	}
	
	public void paint(Graphics g) {
		g.setColor(255, 255, 255);
		g.fillRect(0, 0, width, height);
		refreshBackground(g);
		
		if (this.phase != this.P_FALL_MODE_1) {
			for (int i = this.bricks.length - 1; i > -1; i--) {
				this.bricks[i].paint(g);
			}
			paddle.paint(g);
			if (this.phase == this.P_FIGHT) {
				oppPaddle.paint(g);
			}
		} else {
			for (int i = this.wallBricks.length - 1; i > -1; i--) {
				this.wallBricks[i].paint(g);
			}
		}
		ball.paint(g);
		
		
		if (this.failed || this.win) {
			Font highLightedFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE);
			int itemTop = height / 3 + highLightedFont.getHeight();
			//shadow
			g.setColor(255, 0, 0);		//red
			g.fillRect(0, itemTop, width, highLightedFont.getHeight());
			//string
			g.setColor(255, 255, 255);	//white
			g.setFont(highLightedFont);
			g.drawString((failed)?"You Fail!" : "You Win!", 90, itemTop, Graphics.TOP | Graphics.LEFT);
			g.setColor(255, 255, 255);	//white
			g.setFont(highLightedFont);
			g.drawString("Your Total Score:" + score, 60, itemTop + 25, Graphics.TOP | Graphics.LEFT);
		}
	}
	
	private final void refreshBackground(Graphics g) {
		layerManager.setViewWindow(0, 0, width, height + 10000);
		layerManager.paint(g, 0, bg_y++);
		//g.drawString("pdx=" + paddle_dx + " x=" + ball.x + " y=" + ball.y + " width=" + width + " height=" + height, 0, 0, Graphics.TOP | Graphics.LEFT);
		//g.drawString("dx=" + ball.dx + " dy=" + ball.dy, 0, 30, Graphics.TOP | Graphics.LEFT);
		g.drawString(scoreStr, 0, 0, Graphics.TOP | Graphics.LEFT);
		if (bg_y > 0) {
			bg_y = bg_y0;
		}
	}

	private final void ballMoveForFallMode() {
		if (this.fallModeEnd == false) {
			int beginIndex = 0;
			for (int i = this.numOfLine - 1; i > -1; i--) {
				beginIndex = i * this.numOfBrickPerLine;
				int t = ball.y + ball.r - this.wallBricks[beginIndex].top;
				if (t < 6 && t > -7) {
					int x = ball.x / this.brickWidth;
					if (this.wallBricks[beginIndex + x].type == BrickLv2.T_HIDE) {
						ball_dy = 4;
					} else {
						ball_dy = 0;
						ball.y = this.wallBricks[beginIndex].top - ball.r;
					}
				}
			}
			ball.x += this.ball_dx;
			if (ball.x < ball.r) {
				ball.x = ball.r;
			} else if (ball.x + ball.r > width) {
				ball.x = width - ball.r;
			}
			ball.y += this.ball_dy;
			if (ball.y <= 0) {
				this.failed = true;
			}
			if (ball.y >= height) {
				this.fallModeEnd = true;
			}
		} else {
			ball.x = width / 2;
			ball.y = height - 30 - ball.r;
		}
	}
	
	private final void generateWallForFallMode() {
		int beginIndex = 0;
		int total = 0;
		for (int i = this.numOfLine - 1; i > -1; i--) {
			beginIndex = i * this.numOfBrickPerLine;
			if (this.wallBricks[beginIndex].top < -20) {
				total++;
				if (this.fallModeEnd == false) {
					for (int j = this.numOfBrickPerLine - 1; j > -1; j--) {
						this.wallBricks[beginIndex + j].top = height - 20;
						this.wallBricks[beginIndex + j].setType(BrickLv2.T_FIXED);
					}
					int u = random.nextInt(this.numOfBrickPerLine);
					this.wallBricks[beginIndex + u].type = BrickLv2.T_HIDE;
					u = random.nextInt(this.numOfBrickPerLine);	//generate another gap
					this.wallBricks[beginIndex + u].type = BrickLv2.T_HIDE;
					
					this.addScore();
				}
			}
		}
		if (this.fallModeEnd == true && total == this.numOfLine) {
			this.readyForHitMode = true;
		}
	}


	public void detectCollision() {
		if (ball.x < 0 || ball.x > width - ball.r) {
			ball.hitVertically();
		}
		if (ball.y < 0) {
			if (this.phase == this.P_FIGHT) {
				win = true;
			} else {
				ball.hitHorizontally();
			}
		}
		if (ball.y > height - ball.r) {
			failed = true;
		}
		
		for (int i = this.bricks.length - 1; i > -1; i--) {
			if (detectBrickCollision(this.bricks[i])) {
				break;
			}
		}
		detectPaddleCollision(paddle);
		if (phase == this.P_FIGHT) {
			detectPaddleCollision(oppPaddle);
		}
	}
	
	private void addScore() {
		score++;
		scoreStr = "score:" + score;
	}
	
	private final boolean detectBrickCollision(BrickLv2 b) {
		if (b.type == b.T_HIDE) {
			return false;
		}
		int arcX = ball.x;
		int arcY = ball.y;
		
		int rectLeft = b.left;
		int rectRight = b.left + b.width;
		int rectTop = b.top;
		int rectBottom = b.top + b.height;
		int r = ball.r;
		int rr = r * r;
		

		if (arcX > rectLeft && arcX < rectRight && (arcY + r) >= rectTop && (arcY - r) <= rectBottom) {
			ball.hitVertically();
			if (b.type == b.T_NORMAL) {
				b.setType(b.T_HIDE);
				addScore();
			}
			return true;
		}
		
		if (arcY > rectTop && arcY < rectBottom && (arcX + r) >= rectLeft && (arcX - r) <= rectRight) {
			ball.hitHorizontally();
			if (b.type == b.T_NORMAL) {
				b.setType(b.T_HIDE);
				addScore();
			}
			return true;
		}

		if (((rectRight - arcX) * (rectRight - arcX) + (rectBottom - arcY) * (rectBottom - arcY)) <= rr) {
			ball.hitVertically();
			ball.hitHorizontally();
			if (b.type == b.T_NORMAL) {
				b.setType(b.T_HIDE);
				addScore();
			}
			return true;
		}
		
		if (((rectLeft - arcX) * (rectLeft - arcX) + (rectBottom - arcY) * (rectBottom - arcY)) <= rr) {
			ball.hitVertically();
			ball.hitHorizontally();
			if (b.type == b.T_NORMAL) {
				b.setType(b.T_HIDE);
				addScore();
			}
			return true;
		}
		
		if (((rectLeft - arcX) * (rectLeft - arcX) + (rectTop - arcY) * (rectTop - arcY)) <= rr) {
			ball.hitVertically();
			ball.hitHorizontally();
			if (b.type == b.T_NORMAL) {
				b.setType(b.T_HIDE);
				addScore();
			}
			return true;
		}
		
		if (((rectRight - arcX) * (rectRight - arcX) + (rectTop - arcY) * (rectTop - arcY)) <= rr) {
			ball.hitVertically();
			ball.hitHorizontally();
			if (b.type == b.T_NORMAL) {
				b.setType(b.T_HIDE);
				addScore();
			}
			return true;
		}		
		return false; 
	}
	
	private final boolean detectPaddleCollision(BrickLv2 paddle) {
		int arcX = ball.x;
		int arcY = ball.y;
		
		int rectLeft = paddle.left;
		int rectRight = paddle.left + paddle.width;
		int rectTop = paddle.top;
		int rectBottom = paddle.top + paddle.height;
		int r = ball.r;
		int rr = r * r;

		if (arcX > rectLeft && arcX < rectRight && (arcY + r) >= rectTop && (arcY - r) <= rectBottom) {
			if (paddle.top > height / 2 && ball.dy > -1) {
				ball.dy = -ball.dy;
			} else if (paddle.top < height / 2 && ball.dy < 1) {
				ball.dy = -ball.dy;
			}
			return true;
		}
		
		if (arcY > rectTop && arcY < rectBottom && (arcX + r) >= rectLeft && (arcX - r) <= rectRight) {
			if (paddle.top > height / 2 && ball.dy > -1) {
				ball.dy = -ball.dy;
			} else if (paddle.top < height / 2 && ball.dy < 1) {
				ball.dy = -ball.dy;
			}
			return true;
		}

		if (((rectRight - arcX) * (rectRight - arcX) + (rectBottom - arcY) * (rectBottom - arcY)) <= rr) {
			if (paddle.top > height / 2 && ball.dy > -1) {
				ball.dy = -ball.dy;
			} else if (paddle.top < height / 2 && ball.dy < 1) {
				ball.dy = -ball.dy;
			}
			return true;
		}
		
		if (((rectLeft - arcX) * (rectLeft - arcX) + (rectBottom - arcY) * (rectBottom - arcY)) <= rr) {
			if (paddle.top > height / 2 && ball.dy > -1) {
				ball.dy = -ball.dy;
			} else if (paddle.top < height / 2 && ball.dy < 1) {
				ball.dy = -ball.dy;
			}
			return true;
		}
		
		if (((rectLeft - arcX) * (rectLeft - arcX) + (rectTop - arcY) * (rectTop - arcY)) <= rr) {
			if (paddle.top > height / 2 && ball.dy > -1) {
				ball.dy = -ball.dy;
			} else if (paddle.top < height / 2 && ball.dy < 1) {
				ball.dy = -ball.dy;
			}
			return true;
		}
		
		if (((rectRight - arcX) * (rectRight - arcX) + (rectTop - arcY) * (rectTop - arcY)) <= rr) {
			if (paddle.top > height / 2 && ball.dy > -1) {
				ball.dy = -ball.dy;
			} else if (paddle.top < height / 2 && ball.dy < 1) {
				ball.dy = -ball.dy;
			}
			return true;
		}
		
		return false;
		
	}
	
	private void oppPaddleMove() {
		int ddx = 5;
		int rand = random.nextInt(100);
		if (rand < 10) {
			ddx = 2;
		} else if (rand < 25) {
			ddx = 3;
		} else if (rand < 70) {
			ddx = 4;
		} if (rand < 90) {
			ddx = 5;
		} else {
			ddx = 2;
		}
		if (ball.x > this.oppPaddle.left + this.oppPaddle.width/2) {
			this.oppPaddle.left += ddx;
		} else {
			this.oppPaddle.left -= ddx;
		}
		if (oppPaddle.left < 0) {
			oppPaddle.left = 1;
		} else if (oppPaddle.left + oppPaddle.width > width) {
			oppPaddle.left = width - oppPaddle.width - 1;
		}
	}
	
	
	public void commandAction(Command arg0, Displayable arg1) {
		
	}

	protected void keyPressed(int keyCode) {
		if (GameCanvas.LEFT == getGameAction(keyCode)) {
			this.paddle_dx = -5;
			this.ball_dx = -6;
		} else if (GameCanvas.RIGHT == getGameAction(keyCode)) {
			if (paddle.left + paddle.width < width - 5) {
				this.paddle_dx = 5;
			}
			this.ball_dx = 6;
		}
	}

	protected void keyReleased(int keyCode) {
		this.paddle_dx = 0;
		this.ball_dx = 0;
	}
	
	private final void movePaddle() {
		paddle.left += this.paddle_dx;
		if (paddle.left < 0) {
			paddle.left = 1;
		} else if (paddle.left + paddle.width > width) {
			paddle.left = width - paddle.width - 1;
		}
	}
	
}


